(ns org.mikrosopht.movie
  (:use [clojure.string :only (trim)])
  (:import (org.htmlparser Parser)
           (org.htmlparser.util ParserException)
           (org.htmlparser.visitors NodeVisitor)
           (org.htmlparser.tags Div Span)))

(defn- metacritic-node-visitor [tag]
  (if (and (instance? Span tag) 
           (= (.getAttribute tag "class") "score_value")
           (.startsWith (.getAttribute (.getParent (.getParent tag)) "class") "data metascore score_"))
    (.getChildrenHTML tag)))

(defn- rotten-node-visitor [tag]
  (when (and (instance? Span tag)
             (= (.getAttribute tag "id") "all-critics-meter"))
    (trim (.getChildrenHTML tag))))

(defn- find-score [url node-visitor-fn]
  (let [score (ref nil)
        parser (Parser. url)
        visitor (proxy [NodeVisitor] []
                  (visitTag [tag]
                    (if-let [found-score (node-visitor-fn tag)]
                      (dosync (ref-set score found-score)))))]
    (.visitAllNodesWith parser visitor)
    @score))

(defmulti fetch-score #(first (re-seq #"rottentomatoes|metacritic" %)))

(defmethod fetch-score "metacritic" [url]
  (try
    (find-score url metacritic-node-visitor)
    (catch ParserException e)))

(defmethod fetch-score "rottentomatoes" [url]
  (try 
    (find-score url rotten-node-visitor)
    (catch ParserException e)))

(defmethod fetch-score :default [url])

(dorun (map #(println (fetch-score %)) *command-line-args*))
